#include "short_test.h"
#include "main.h"
#include <stdio.h>
// static inline void

struct Pin pin_list1[] = {
    {P50_GPIO_Port, P50_Pin, "P50"},                       // 0
    {P49_GPIO_Port, P49_Pin, "P49"},                       // 1
    {P48_GPIO_Port, P48_Pin, "P48"},                       // 2
    {P47_46_GPIO_Port, P47_46_Pin, "P47-46"},              // 3
    {P45_44_43_GPIO_Port, P45_44_43_Pin, "P45_44_43_Pin"}, // 4
    {P42_GPIO_Port, P42_Pin, "P42"},                       // 5
    {P41_GPIO_Port, P41_Pin, "P41"},                       // 6
    {NULL, 0, "GND-P40"},                                  // 7
    {P39_GPIO_Port, P39_Pin, "P39"},                       // 8
    {P38_GPIO_Port, P38_Pin, "P38"},                       // 9
};
struct Pin pin_list2[] = {
    {P18_GPIO_Port, P18_Pin},           // 0
    {P17_GPIO_Port, P17_Pin},           // 1
    {P16_GPIO_Port, P16_Pin},           // 2
    {P15_GPIO_Port, P15_Pin},           // 3
    {NULL, 0, "GND-P14"},               // 4
    {P13_10_9_GPIO_Port, P13_10_9_Pin}, // 5
    {P12_11_GPIO_Port, P12_11_Pin},     // 6
    {P13_10_9_GPIO_Port, P13_10_9_Pin}, // 7
    {P8_GPIO_Port, P8_Pin},             // 8
    {P7_GPIO_Port, P7_Pin},             // 9
    {P6_GPIO_Port, P6_Pin},             // 10
    {P5_GPIO_Port, P5_Pin},             // 11
    {P4_GPIO_Port, P4_Pin},             // 12
    {P3_GPIO_Port, P3_Pin},             // 13
    {P2_GPIO_Port, P2_Pin},             // 14
    {P1_GPIO_Port, P1_Pin},             // 15
};

void pin_set_input_pu(struct Pin *pin)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = pin->nbr;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(pin->port, &GPIO_InitStruct);
}

void pin_set_input_pd(struct Pin *pin)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = pin->nbr;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(pin->port, &GPIO_InitStruct);
}

void pin_set_output(struct Pin *pin, int state)
{
    HAL_GPIO_WritePin(pin->port, pin->nbr, (state == 0) ? GPIO_PIN_RESET : GPIO_PIN_SET);
}

int pin_read(struct Pin *pin)
{
    return (HAL_GPIO_ReadPin(pin->port, pin->nbr) == GPIO_PIN_SET) ? 1 : 0;
}

int detect_short(struct Pin *pin_list, int size)
{
    uint16_t state = 0;
    //printf("size is %d\n\r", size);
    // HAL_GPIO_TogglePin(LED_BUSY_GPIO_Port, LED_BUSY_Pin);
    HAL_Delay(100);

    /*for (int i = 0; i < size - 1; i++) {
        printf("-- index: %d pin : %d\n\r", i, (&pin_list[i])->nbr);
    }*/
    for (int i = 0; i < size - 1; i++)
    {
        printf("-- index: i=%d, i+1=%d\n\r", i, i + 1);

        // printf("test %d\n\r",i);
        if (((&pin_list[i])->nbr == 0))
        {
            // 当前引脚是地, 跳过这次判断
            printf("Current pin %d is GND\n\r", i);
            // continue;
        }
        else
        {
            // 当前引脚不是地
            printf("Current pin %d is not GND\n\r", i);

            if (((&pin_list[i + 1])->nbr == 0))
            {
                // 要是下一个引脚是地, 只做当前引脚上拉, 看结果是不是为0的判断
                printf("pin %d next pin is GND\n\r", i);
                // 当前引脚设置为输入上拉,
                pin_set_input_pu(&pin_list[i]);
                HAL_Delay(10);

                // 下个引脚输出低
                // pin_set_output(&pin_list[i + 1], 0);
                // 读当前引脚, 读到高是正常, 读到低是短路

                if (pin_read(&pin_list[i]) == 0)
                {
                    printf("%d and %d is short\n\r", i, i + 1);
                    state = 1;
                    test_NG();
                }
            }
            else
            {
                // 当前引脚和下一个引脚都不是地, 那么两种判断都做
                printf("pin %d\n\r", i);
                // 当前脚设置为输入下拉
                pin_set_input_pd(&pin_list[i]);
                // 让下一个引脚输出高
                pin_set_output(&pin_list[i + 1], 1);
                HAL_Delay(10);
                // 判断当前引脚,低是正常, 高就是短路了,
                if (pin_read(&pin_list[i]) != 0)
                {
                    printf("%d and %d is short\n\r", i, i + 1);
                    state = 1;
                    test_NG();
                }
                /*
                // 当前引脚设置为输入上拉,
                pin_set_input_pu(&pin_list[i]);
                // 下个引脚输出低
                pin_set_output(&pin_list[i + 1], 0);
                // 读当前引脚, 读到高是正常, 读到低是短路
                if (pin_read(&pin_list[i]) == 0) {
                    printf("%d and %d is short\n\r",i,i+1);
                    return 1;
                }*/
            }
        }
    }

    return state;
}

void LED_state(uint8_t LED_busy, uint8_t LED_OK, uint8_t LED_NG)
{
    HAL_GPIO_WritePin(LED_BUSY_GPIO_Port, LED_BUSY_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_NG_GPIO_Port, LED_NG_Pin, GPIO_PIN_SET);
    if (LED_busy == 0)
    {
        HAL_GPIO_WritePin(LED_BUSY_GPIO_Port, LED_BUSY_Pin, GPIO_PIN_SET);
    }
    else if (LED_busy == 1)
    {
        HAL_GPIO_WritePin(LED_BUSY_GPIO_Port, LED_BUSY_Pin, GPIO_PIN_RESET);
    }

    if (LED_OK == 0)
    {
        HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_SET);
    }
    else if (LED_OK == 1)
    {
        HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_RESET);
    }

        if (LED_NG == 0)
    {
        HAL_GPIO_WritePin(LED_NG_GPIO_Port, LED_NG_Pin, GPIO_PIN_SET);
    }else if (LED_NG == 1)
    {
        HAL_GPIO_WritePin(LED_NG_GPIO_Port, LED_NG_Pin, GPIO_PIN_RESET);
    }
}

void test_NG(void)
{
    LED_state(0,0,1);
    printf("connector is NG\n\r");
    while (1)
    {
        HAL_Delay(100);
    }
    
}

void short_test(void)
{
    int result = 0;
    //HAL_GPIO_WritePin(LED_BUSY_GPIO_Port, LED_BUSY_Pin, GPIO_PIN_RESET);
    //HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_SET);
    //HAL_GPIO_WritePin(LED_NG_GPIO_Port, LED_NG_Pin, GPIO_PIN_SET);
    LED_state(1,0,0);
    HAL_Delay(100);
    result += detect_short(pin_list1, sizeof(pin_list1) / sizeof(struct Pin));
    printf("list 1 result is %d\n\r", result);
    result += detect_short(pin_list2, sizeof(pin_list2) / sizeof(struct Pin));
    printf("list 2 result is %d\n\r", result);
    if (result != 0)
    {
        LED_state(0,0,1);
        printf("connector is NG\n\r");
    }
    else
    {
        LED_state(0,1,0);
        printf("test OK\n\r");
    }
}